package com.example.mweather;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.mweather.adapter.DailyAdapter;
import com.example.mweather.adapter.HourlyAdapter;
import com.example.mweather.beans.DailyItemBean;
import com.example.mweather.beans.HourlyItemBean;
import com.example.mweather.beans.WeatherDaily;
import com.example.mweather.beans.WeatherHourly;
import com.example.mweather.beans.WeatherRealtime;
import com.example.mweather.utils.WeatherUtil;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.gson.Gson;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class WeatherMainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_LOCATION = 100;
    private Toolbar toolbar;
    private CollapsingToolbarLayout collapsingToolbar;
    // 默认城市及经纬度
    private String city = "天津市";
    private double lat = 39.085318;
    private double lng = 117.201509;
    private TextView tvTempRealtime, tvTempMaxMin, tvDescription;
    private RecyclerView rvHourly, rvDaily;
    private ImageView ivBackground;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather_main);
        ivBackground = findViewById(R.id.ivBackground);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        collapsingToolbar = findViewById(R.id.collapsingToolbar);
        collapsingToolbar.setExpandedTitleColor(Color.WHITE);
        collapsingToolbar.setCollapsedTitleTextColor(Color.WHITE);
        tvTempRealtime = findViewById(R.id.tvTempRealtime);
        tvTempMaxMin = findViewById(R.id.tvTempMaxMin);
        tvDescription = findViewById(R.id.tvDescription);
        rvHourly = findViewById(R.id.rvHourly);
        rvDaily = findViewById(R.id.rvDaily);
        fetchWeatherData();
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            // 已获取定位权限，获取当前城市信息
            getCurrentCityInfo();
        } else {
            // 未获取定位权限，申请定位权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_LOCATION);
        }
    }

    /**
     * 获取天气数据
     */
    private void fetchWeatherData() {
        SharedPreferences preferences = getSharedPreferences("cities", MODE_PRIVATE);
        Integer theme = preferences.getInt("theme", R.mipmap.bg_main_theme1);
        ivBackground.setImageResource(theme);
        city = preferences.getString("city", "天津市");
        lat = preferences.getFloat("lat", 39.085318f);
        lng = preferences.getFloat("lat", 117.201509f);
        collapsingToolbar.setTitle(city);
        // 获取默认城市实时天气数据
        getWeatherRealtime();
        // 获取默认城市天级别天气数据
        getWeatherDaily();
        // 获取默认城市小时级别天气数据
        getWeatherHourly();
    }

    @Override
    protected void onResume() {
        super.onResume();
        fetchWeatherData();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_LOCATION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 申请权限且用户同意授予权限后，获取当前城市信息
                getCurrentCityInfo();
            } else {
                Toast.makeText(this, "获取当前所在城市需要定位权限", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.search:
                startActivity(new Intent(WeatherMainActivity.this, SearchActivity.class));
                break;
            case R.id.theme:
                startActivity(new Intent(WeatherMainActivity.this, ThemeActivity.class));
                break;
            case R.id.share:
                Intent shareIntent = new Intent(Intent.ACTION_SEND);
                shareIntent.setType("text/plain");
                shareIntent.putExtra(Intent.EXTRA_TEXT, "飞飞天气，下载地址：https://www.ffweather.com/download.html");
                startActivity(Intent.createChooser(shareIntent, "分享到"));
                break;
            case R.id.manage:
                startActivity(new Intent(WeatherMainActivity.this, ManageActivity.class));
                break;
            default:
                super.onOptionsItemSelected(item);
        }
        return true;
    }

    /**
     * 使用系统自定的API获取位置信息
     *
     * @return
     */
    private void getCurrentCityInfo() {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(true);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        String provider = locationManager.getBestProvider(criteria, true);
        if (provider != null) {
            Location location = locationManager.getLastKnownLocation(provider);
            if (location != null) {
                // 定位成功后，获取当前定位城市的天气数据
                lat = location.getLatitude();
                lng = location.getLongitude();
                fetchWeatherData();
                // 如果位置信息不为空，则根据位置信息解析得到城市信息
                Geocoder gc = new Geocoder(this, Locale.getDefault());
                try {
                    List<Address> result = gc.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
                    if (result.size() > 0) {
                        collapsingToolbar.setTitle(result.get(0).getAdminArea() + result.get(0).getSubLocality());
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 获取实时天气数据
     */
    private void getWeatherRealtime() {
        try {
            OkHttpClient client = new OkHttpClient();
            String url = "https://api.caiyunapp.com/v2.5/580dt8BUSzfAlnvj/" + lng + "," + lat + "/realtime.json";
            Request request = new Request.Builder().url(url).build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String repContent = response.body().string();
                        Gson gson = new Gson();
                        WeatherRealtime weatherRealtime = gson.fromJson(repContent, WeatherRealtime.class);
                        runOnUiThread(() -> {
                            tvTempRealtime.setText((int) weatherRealtime.getResult().getRealtime().getTemperature() + "");
                            tvDescription.setText(WeatherUtil.genDescriptionBySkycon(weatherRealtime.getResult().getRealtime().getSkycon()) + "  空气" + weatherRealtime.getResult().getRealtime().getAir_quality().getDescription().getChn());
                        });
                    } else {
                        Log.e(WeatherMainActivity.this.getLocalClassName(), "获取实时天气数据失败");
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取天级别天气数据
     */
    private void getWeatherDaily() {
        try {
            OkHttpClient client = new OkHttpClient();
            String url = "https://api.caiyunapp.com/v2.6/580dt8BUSzfAlnvj/" + lng + "," + lat + "/daily?dailysteps=15";
            Request request = new Request.Builder().url(url).build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String repContent = response.body().string();
                        Gson gson = new Gson();
                        WeatherDaily weatherDaily = gson.fromJson(repContent, WeatherDaily.class);
                        runOnUiThread(() -> {
                            int max = (int) weatherDaily.getResult().getDaily().getTemperature().get(0).getMax();
                            int min = (int) weatherDaily.getResult().getDaily().getTemperature().get(0).getMin();
                            tvTempMaxMin.setText(max + " / " + min + "\u00AD°C");
                            // 多日预报
                            List<DailyItemBean> list = DailyItemBean.getList(weatherDaily);
                            LinearLayoutManager layoutManager = new LinearLayoutManager(WeatherMainActivity.this);
                            layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
                            rvDaily.setLayoutManager(layoutManager);
                            rvDaily.setAdapter(new DailyAdapter(list));

                        });
                    } else {
                        Log.e(WeatherMainActivity.this.getLocalClassName(), "获取天级别天气数据失败");
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取小时级别天气数据
     */
    private void getWeatherHourly() {
        try {
            OkHttpClient client = new OkHttpClient();
            String url = "https://api.caiyunapp.com/v2.6/580dt8BUSzfAlnvj/" + lng + "," + lat + "/hourly?hourlysteps=24";
            Request request = new Request.Builder().url(url).build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String repContent = response.body().string();
                        Gson gson = new Gson();
                        WeatherHourly weatherHourly = gson.fromJson(repContent, WeatherHourly.class);
                        runOnUiThread(() -> {
                            List<HourlyItemBean> list = HourlyItemBean.getList(weatherHourly);
                            LinearLayoutManager layoutManager = new LinearLayoutManager(WeatherMainActivity.this);
                            layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
                            rvHourly.setLayoutManager(layoutManager);
                            rvHourly.setAdapter(new HourlyAdapter(list));
                        });
                    } else {
                        Log.e(WeatherMainActivity.this.getLocalClassName(), "获取小时级别天气数据失败");
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}